package de.gameduell.net.src.communication {
	import de.gameduell.framework.util.FlashVars;	
	import de.gameduell.framework.application.protocol.Protocol;
	import de.gameduell.framework.application.net.SimpleURLRequest;
	import de.gameduell.framework.application.protocol.SingleplayerProtocol;
	import de.gameduell.framework.debug.Debug;
	import de.gameduell.net.src.message.IMessage;

	import com.hurlant.crypto.rsa.RSAKey;
	import com.hurlant.util.Base64;

	import flash.events.DataEvent;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.ByteArray;
	import flash.utils.Timer;

	public class FaceBookCommunication extends Standalone {
		
		private static const MAX_RETRIES:int = 3;
		private static const RETRY_TIMER:int = 4000;
		private static const TOTAL_TIME:int  = 15000;
		private var retries:int    = 0;
		private var finalScore:int = -1;
		private var totalTimer:Timer;
		
		public function FaceBookCommunication() {
			super();
			totalTimer = new Timer(TOTAL_TIME, 1);
			totalTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onScoreConfirmed);
		}

		override public function send(requestType:String, parameters:Array):IMessage {
			switch(requestType) {
				case SingleplayerProtocol.SCORE:
					dumpScore(int(parameters[0]));
					break;
				case Protocol.ABORT:
					// do nothing until score dump is confirmend ...
					break;
				case SingleplayerProtocol.END:
					// do nothing until score dump is confirmend ...
					break;
				default:
					return super.send(requestType, parameters);
			}
			var message:IMessage = protocol.createMessage(requestType, parameters, messageQueue.nextMessageId);
			return message;
		}

		protected function dumpScore(aScore:int):void {
			if(finalScore == -1){
				finalScore = aScore;
				totalTimer.start();
			}
			try {
				if(settings.sendScore && settings.sendScoreURL != null) {
					var loadingTime:String	  = FlashVars.getKeyValue(FlashVars.LOADING_TIME);
					var modulus:String 		  = "87351a5d683643095e73de2f5669c0abb699a912342cddb72c09fa06457cbba2def0516f560208b3b284b3cbddaa9c111d3d24513989cda901d4f0fc10c7ce69";
					var publicExponent:String = "10001";
					var rsa:RSAKey 			  = RSAKey.parsePublicKey(modulus, publicExponent);
					var src:ByteArray 		  = Base64.decodeToByteArray(Base64.encode(String(aScore)));
					var destination:ByteArray = new ByteArray;
					rsa.encrypt(src, destination, src.length);
					var scoreString:String 	   = Base64.encodeByteArray(destination);
					var urlEncodedScore:String = encodeURIComponent(scoreString);
					urlEncodedScore 		   = settings.encryptScore ? urlEncodedScore : String(aScore);
					FlashVars.setKeyValue(FlashVars.ENCRYPTED_SCORE, urlEncodedScore);
					var scoreRequest:SimpleURLRequest = new SimpleURLRequest(unescape(settings.sendScoreURL) + "&" + settings.scoreParam + "=" + urlEncodedScore+"&"+FlashVars.LOADING_TIME+"="+loadingTime);
					scoreRequest.addEventListener(SimpleURLRequest.ERROR, onScoreError);
					scoreRequest.addEventListener(DataEvent.DATA, onScoreConfirmed);
					scoreRequest.load();
				}
			}catch(e:Error) {
				Debug.trace("FaceBookCommunication::dumpScore() - loader contains old settings class: dumpScore() not available", Debug.WARNING);
			}
		}
		
		private function resendScore(event:Event = null):void {
			Debug.trace("FacebookCommunication::resendScore");
			dumpScore(finalScore);
		}

		private function onScoreConfirmed(event:Event = null):void {
			Debug.trace("FacebookCommunication::onScoreConfirmed");
			dispatchEvent(new ServerMessageEvent(SingleplayerProtocol.LEAVE,[]));
		}
		
		private function onScoreError(event:Event):void {
			Debug.trace("FacebookCommunication::onScoreError");
			if(retries < MAX_RETRIES){
				retries++;
				var resendTimer:Timer = new Timer(RETRY_TIMER, 1);
				resendTimer.addEventListener(TimerEvent.TIMER_COMPLETE, resendScore);
				resendTimer.start();	
			}else{
				Debug.trace("FacebookCommunication::onScoreError: score not submitted - giving up", Debug.ERROR);
				totalTimer.stop();
				dispatchEvent(new ServerMessageEvent(SingleplayerProtocol.LEAVE,[]));
			}
		}
	}
}
